package org.example.aitest.utils.gen;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.example.aitest.dto.TableColumn;
import org.example.aitest.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 将excel文件内容按顺序set到实体类中
 * 返回的是实体类的集合，不包括id
 * */
@Component
public class ExcelUtil {


    /**
     * key:对应第几张表
     * value:key:对应列的中文首拼音
     *       value:对应列的数据
     * */
    static Map<Integer,Map<String,String>> staticMap = new HashMap<>();

    /**
     * key:对应第几张表
     * value:key对应选取的第几列
     *       value:取的同上value的集合
     * */
    static Map<Integer,Map<Integer,Map<String,String>>> stMap = new HashMap<>();

    @Autowired
    public DynamicTableGenerator dynamicTableGenerator;
    @Autowired
    public DynamicDataService dataService;

    /**
     * 用传入的文件某一列来比较之前用excel自动建表的内容，若匹配上则将数据库对应内容填入该表对应下面，如果匹配上，但是后面内容没有对应填入位置则依次往后填入
     * 返回结果为，map,key为确定的第几张表
     * value为map结构，valueKey为对应excel表的第几行数据，value的value为数据集
     * */
    public static List<TableMsg> compare(MultipartFile file) throws Exception {
        String name = file.getOriginalFilename();

        // 文件后缀
        String la = name.substring(name.lastIndexOf(".")+1);
        // 处理文件
        if(la.equals("xlsx")){
            XSSFWorkbook excel = new XSSFWorkbook(file.getInputStream());
            // 有几张表
            int sheets = excel.getNumberOfSheets();

            // 实际上不需要其返回数据，只需要其设置的全局map对象
            setValuesXLSX(excel,sheets);

            //将该全局map返回-使用深拷贝，防止清理时将该返回map清理掉
//            Map<Integer,Map<Integer,Map<String,String>>> map = deepCopy(stMap);
            //用完清理该map
//            stMap.clear();

            List<TableMsg> tableMsgs = new ArrayList<>();
            for (Integer i : stMap.keySet()) {
                Map<Integer, Map<String, String>> integerListMap = stMap.get(i);
                XSSFSheet sheet = excel.getSheetAt(i);

                for (Integer integer : integerListMap.keySet()) {
                    // 以integer的下一行开始找数据，行为基础扫描
                    //总行数
                    int lastRowNum = sheet.getLastRowNum();
                    // 表名行
                    XSSFRow row1 = sheet.getRow(integer);



                    int lastCellNum1 = row1.getLastCellNum();
                    // 以列为基础，一列一列往后找
                    for (int j = 0; j < lastCellNum1; j++) {
                        TableMsg tableMsg = null;

                        // 只有在有数据的列才需要此数据
                        String hName = null;
                        List<Object> list = new ArrayList<>();

                        for (int k = integer+1; k <= lastRowNum; k++) {
                            XSSFRow row = sheet.getRow(k);
                            XSSFCell cell = row.getCell(j);
                            if(cell != null){
                                // 取出该列原始内容
                                DataFormatter formatter = new DataFormatter();
                                String stringCellValue = formatter.formatCellValue(cell);
                                if(StringUtils.isNotEmpty(stringCellValue)){

                                    list.add(stringCellValue);
                                    /**
                                     * 确定的表行数据，用来封装返回
                                     * 例如：以excel表第三行为基础往下做数据匹配
                                     * 第一列为订单编号，往下的行为对应的订单编号，则取出：订单编号这个数据，后面加上该行下所有内容
                                     * */
                                    XSSFCell cell1 = row1.getCell(j);
                                    String stringCellValue1 = formatter.formatCellValue(cell1);
                                    String firstLetters = PinyinUtils.getFirstLetters(stringCellValue1);
                                    hName = PinyinUtils.sanitizeTableName(firstLetters);

                                    tableMsg = new TableMsg();
                                    tableMsg.setCellYName(stringCellValue1);
                                    tableMsg.setBNo(i);
                                    tableMsg.setHNo(integer);
                                    tableMsg.setLNo(j);
                                    tableMsg.setCellName(hName);
                                }
                            }
                        }
                        if(tableMsg != null){
                            tableMsg.setList(list);
                            tableMsgs.add(tableMsg);
                        }
                    }
                }
            }

            stMap.clear();

            return tableMsgs;
        }
        return null;
    }

    // 深拷贝方法
    private static Map<Integer, Map<Integer, Map<String, String>>> deepCopy(
            Map<Integer, Map<Integer, Map<String, String>>> original) {

        Map<Integer, Map<Integer, Map<String, String>>> copy = new HashMap<>();
        for (Map.Entry<Integer, Map<Integer, Map<String, String>>> entry : original.entrySet()) {
            Map<Integer, Map<String, String>> innerCopy = new HashMap<>();
            for (Map.Entry<Integer, Map<String, String>> innerEntry : entry.getValue().entrySet()) {
                innerCopy.put(innerEntry.getKey(), new HashMap<>(innerEntry.getValue()));
            }
            copy.put(entry.getKey(), innerCopy);
        }
        return copy;
    }

    /**
     * 通过excel文件在数据库中添加excel对应表，并将excel文件内容对应填入，以第一次出现的最长一行为基础建表，以该行往下内容为数据填入
     * */
    public void createTableToExcel(MultipartFile file){
        String name = file.getOriginalFilename();

        // 文件后缀
        String la = name.substring(name.lastIndexOf(".")+1);
        try {
            if(la.equals("xlsx")){
                XSSFWorkbook excel = new XSSFWorkbook(file.getInputStream());

                Map<String, Object> tableColumnsXLSX = getTableColumnsXLSX(excel);
                // 开始设置生成数据库表
                if (tableColumnsXLSX.containsKey("table")) { //先创建数据库
                    Map<Integer, List<TableColumn>> tableColumns = (Map<Integer, List<TableColumn>>) tableColumnsXLSX.get("table");
                    for (Integer integer : tableColumns.keySet()) {
                        // 表名
                        String tableName = PinyinUtils.getFirstLetters(name + "_" + integer);
                        //对表名处理
                        String res_name = PinyinUtils.sanitizeTableName(tableName);
                        //表格属性集合
                        List<TableColumn> tableColumns1 = tableColumns.get(integer);
                        //一个excel文件里面可能有多个excel表，一个表就生成一个数据库
                        dynamicTableGenerator.createTable(res_name, tableColumns1,name,1);
                    }
                }

                if (tableColumnsXLSX.containsKey("tableIn")) {//生成数据库后动态添加数据
                    Map<Integer, List<List<Map<String, Object>>>> tab = (Map<Integer, List<List<Map<String, Object>>>>) tableColumnsXLSX.get("tableIn");
                    for (Integer integer : tab.keySet()) {
                        // 表名
                        String tableName = PinyinUtils.getFirstLetters(name + "_" + integer);
                        //对表名处理
                        String res_name = PinyinUtils.sanitizeTableName(tableName);
                        // 一张表所有行的数据
                        List<List<Map<String, Object>>> lists = tab.get(integer);
                        for (List<Map<String, Object>> list : lists) { //只要是一行就行
                            //一行的数据
                            for (int i = 0; i < list.size(); i++) {
                                //按表列名动态添加数据
                                Map<String, Object> objectMap = list.get(i);
                                dataService.insertData(res_name, objectMap);
                            }
                        }
                    }
                }
            }else if(la.equals("xls")){
                HSSFWorkbook excel = new HSSFWorkbook(file.getInputStream());
                Map<String, Object> tableColumnsXLSX = ExcelUtil.getTableColumnsXLS(excel);
                // 开始设置生成数据库表
                if (tableColumnsXLSX.containsKey("table")) { //先创建数据库
                    Map<Integer, List<TableColumn>> tableColumns = (Map<Integer, List<TableColumn>>) tableColumnsXLSX.get("table");
                    for (Integer integer : tableColumns.keySet()) {
                        // 表名
                        String tableName = PinyinUtils.getFirstLetters(name + "_" + integer);
                        //对表名处理
                        String res_name = PinyinUtils.sanitizeTableName(tableName);
                        //表格属性集合
                        List<TableColumn> tableColumns1 = tableColumns.get(integer);
                        //一个excel文件里面可能有多个excel表，一个表就生成一个数据库
                        dynamicTableGenerator.createTable(res_name, tableColumns1,name,1);
                    }
                }

                if (tableColumnsXLSX.containsKey("tableIn")) {//生成数据库后动态添加数据
                    Map<Integer, List<List<Map<String, Object>>>> tab = (Map<Integer, List<List<Map<String, Object>>>>) tableColumnsXLSX.get("tableIn");
                    for (Integer integer : tab.keySet()) {
                        // 表名
                        String tableName = PinyinUtils.getFirstLetters(name + "_" + integer);
                        //对表名处理
                        String res_name = PinyinUtils.sanitizeTableName(tableName);
                        // 一张表所有行的数据
                        List<List<Map<String, Object>>> lists = tab.get(integer);
                        for (List<Map<String, Object>> list : lists) { //只要是一行就行
                            //一行的数据
                            for (int i = 0; i < list.size(); i++) {
                                //按表列名动态添加数据
                                Map<String, Object> objectMap = list.get(i);
                                dataService.insertData(res_name, objectMap);
                            }
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**  TODO 此方法调用要求数据库先建好表后，会按顺序依次添加
     * excel:后缀为.xls的excel表
     * clazz:要set的对象实体类
     * bb:读取第几张表
     * dh:读取第几行来确定循环次数，即确定set次数
     * bh:从第几行开始遍历读取数据
     * bl:从第几列开始便利读取数据
     * 返回类型即为传入类型
     * */
    public static <T> List<T> xls(HSSFWorkbook excel, Class<T> clazz, Integer bb, Integer dh, Integer bh, Integer bl) throws Exception {
        HSSFSheet sheet = excel.getSheetAt(bb-1);
        HSSFRow row = sheet.getRow(dh);
        // 列数
        int lastCellNum = row.getLastCellNum();
        //行数
        int lastRowNum = sheet.getLastRowNum();

        //所有行的数据集合对象
        List<T> objects = new ArrayList<>();
        for (int i = bh-1; i <= lastRowNum; i++) { //从第四行开始遍历
            //一行的数据集合
            List<String> list = new ArrayList<>();
            T object = clazz.newInstance();

            HSSFRow row1 = sheet.getRow(i);
            for (int j = bl-1; j < lastCellNum; j++) {
                HSSFCell cell = row1.getCell(j);
                String stringCellValue = "空";
                if (cell != null) {
                    switch (cell.getCellType()) {
                        case HSSFCell.CELL_TYPE_STRING:
                            stringCellValue = cell.getStringCellValue();
                            break;
                        case HSSFCell.CELL_TYPE_NUMERIC:
                            if (DateUtil.isCellDateFormatted(cell)) {
                                stringCellValue = DateUtils.parseDate2String(cell.getDateCellValue());
                            } else {
                                // 数字以原格式输出，避免添加0
                                DataFormatter formatter = new DataFormatter();
                                stringCellValue = formatter.formatCellValue(cell);
                            }
                            break;
                        case HSSFCell.CELL_TYPE_BOOLEAN:
                            stringCellValue = String.valueOf(cell.getBooleanCellValue());
                            break;
                        case HSSFCell.CELL_TYPE_FORMULA:
                            stringCellValue = cell.getCellFormula();
                            break;
                        default:
                            stringCellValue = "空";
                    }
                }
                list.add(stringCellValue);
            }
            invokeAllSetters(object,list);
            if(isObjNull(object)){
                objects.add(object);
            }
        }
        return objects;
    }

    /**
     * obj 目标对象
     * values 要设置的值
     * */
    public static void invokeAllSetters(Object obj, List<String> values){
        Class<?> clazz = obj.getClass();
        //获取所有字段（按申明顺序）
        List<Field> fields = Arrays.asList(clazz.getDeclaredFields());
        // 获取所有set方法并按方法名排序（保持申明顺序）
        Map<String, Method> setterMap = Arrays.stream(clazz.getMethods()).filter(method -> method.getName().startsWith("set") &&
                        method.getParameterCount() == 1 && method.getReturnType() == void.class)
                .collect(Collectors.toMap(
                        Method::getName,
                        m -> m,
                        (m1,m2) -> m1)); //如果有重名方法，取第一个

        // 准备要调用的set方法列表(按字段顺序)
        List<Method> orderedSetters = new ArrayList<>();

        for (Field field : fields) {
            String setterName = "set" + capitalize(field.getName());
            Method setter = setterMap.get(setterName);
            if(setter != null){
                // 跳过第一个setId
                if("setId".equals(setterName)){
                    continue;
                }
                orderedSetters.add(setter);
            }

        }
        //依次调用set方法
        for (int i = 0; i < orderedSetters.size(); i++) {

            String stringValue = values.get(i);
            if("空".equals(stringValue)){
                continue;
            }
            Method setter = orderedSetters.get(i);

            try {
                Class<?> parameterType = setter.getParameterTypes()[0];
                Object converted = convertStringToType(stringValue, parameterType);
                setter.invoke(obj,converted);
            }catch (Exception e){
                throw new RuntimeException("设置属性[" + setter.getName() +
                        "]时出错: " + e.getMessage(), e);
            }
        }
    }

    private static String capitalize(String str) {
        if (str == null || str.isEmpty()) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    // 将字符串转化为目标类型
    private static Object convertStringToType(String value, Class<?> targetType){
        if(StringUtils.isEmpty(value)){
            return null;
        }

        try {
            if (targetType == String.class) {
                return value;
            } else if (targetType == Integer.class || targetType == int.class) {
                return Integer.parseInt(value);
            } else if (targetType == Long.class || targetType == long.class) {
                return Long.parseLong(value);
            } else if (targetType == Double.class || targetType == double.class) {
                return Double.parseDouble(value);
            } else if (targetType == Float.class || targetType == float.class) {
                return Float.parseFloat(value);
            } else if (targetType == Boolean.class || targetType == boolean.class) {
                return Boolean.parseBoolean(value);
            } else if (targetType == BigDecimal.class) {
                // 移除所有非数字字符（保留小数点、负号和数字）
                String cleanedValue = value.replaceAll("[^\\d.-]", "");
                return new BigDecimal(cleanedValue);
            } else if (targetType == Date.class) {
                try {
                    return com.alibaba.fastjson2.util.DateUtils.parseDate(value);
                } catch (Exception e) {
                    // 尝试下一种格式
                }
                throw new IllegalArgumentException("无法解析日期: " + value);
            } else {
                throw new IllegalArgumentException("不支持的类型转换: String -> " + targetType.getName());
            }
        }catch (Exception e){
            throw new IllegalArgumentException("无法将值[" + value +
                    "]转换为类型[" + targetType.getName() + "]", e);
        }
    }

    public static <T> List<T> xlsx(XSSFWorkbook excel, Class<T> clazz, Integer bb, Integer dh, Integer bh, Integer bl) throws Exception {
        XSSFSheet sheet = excel.getSheetAt(bb - 1);
        XSSFRow row = sheet.getRow(dh);
        // 列数
        int lastCellNum = row.getLastCellNum();
        //行数
        int lastRowNum = sheet.getLastRowNum();

        //所有行的数据集合对象
        List<T> objects = new ArrayList<>();
        for (int i = bh-1; i <= lastRowNum; i++) {
            //一行的数据集合
            List<String> list = new ArrayList<>();
            T object = clazz.newInstance();

            XSSFRow row1 = sheet.getRow(i);
            for (int j = bl-1; j < lastCellNum; j++) {
                XSSFCell cell = row1.getCell(j);
                String stringCellValue = "空";
                if (cell != null) {
                    if(cell.getCellType() == HSSFCell.CELL_TYPE_STRING){
                        stringCellValue = cell.getStringCellValue();
                    } else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
                        if (DateUtil.isCellDateFormatted(cell)) {
                            stringCellValue = DateUtils.parseDate2String(cell.getDateCellValue());
                        } else {
                            // 数字以原格式输出，避免添加0
                            DataFormatter formatter = new DataFormatter();
                            stringCellValue = formatter.formatCellValue(cell);
                        }
                    } else if (cell.getCellType() == HSSFCell.CELL_TYPE_BOOLEAN) {
                        stringCellValue = String.valueOf(cell.getBooleanCellValue());
                    } else if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
                        stringCellValue = cell.getCellFormula();
                    }else {
                        stringCellValue = "空";
                    }
                }
                list.add(stringCellValue);
            }
            invokeAllSetters(object,list);
            if(isObjNull(object)){
                objects.add(object);
            }
        }
        return objects;
    }

    // 判断对象是否全为空
    private static boolean isObjNull(Object object){
        // 利用反射检查所有字段是否为空，若全为空则不添加
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object valu = field.get(object);
                if(valu != null){
                    // 任意字段不为空则实体类不为空
                    return true;
                }
            }catch (IllegalAccessException e){
                e.printStackTrace();
            }
        }
        return false;
    }

    /** TODO 此方法为根据excel表动态创建表到数据库，并将excel表内容动态添加进表，若表已存在则会创建失败
     * 实现读取指定行不为空的的表格
     * 返回类型为List<TableColumn>,将excel表格与数据库表对应，类型根据表格下面不为空的类型确定，若都为空则类型为VARCHAR
     * */
    public static Map<String,Object> getTableColumnsXLSX(XSSFWorkbook excel) throws Exception {
        //有几张表创建几个数据库
        int sheets = excel.getNumberOfSheets();

        // 获取设置字段名
        Map<Integer, Map<String, List<String>>> mapMap = setValuesXLSX(excel, sheets);

        Map<String,Object> map1 = new HashMap<>();

        Map<Integer,List<TableColumn>> map = new HashMap<>();
        // 设置字段类型
        // 确定从第几行开始循环往下确定数据类型
        Set<Integer> integers = mapMap.keySet();

        Map<Integer,List<List<Map<String,Object>>>> map2 = new HashMap<>();

        for (Integer integer : integers) {
            List<List<Map<String,Object>>> listList = new ArrayList<>();

            Map<String, List<String>> stringListMap = mapMap.get(integer);
            Set<String> strings = stringListMap.keySet();
            for (String string : strings) { //此循环实际上肯定只有一个
                List<String> list = stringListMap.get(string);
                //依次取出列名，对出现重复名称的列名做处理
                for (int i = 0; i < list.size(); i++) {
                    for (int j = i + 1; j < list.size(); j++) {
                        if(list.get(i).equals(list.get(j))){//依次和后面数据比较，若出现相同名，则修改
                            String s = list.get(j);
                            String new_name = s + "_"+ j; //将该重名项后添加对应列数信息，防止重名
                            list.set(j, new_name);
                        }
                    }
                }

                List<String> list1 = setValuesTypeXLSX(excel, integer, string, list.size());

                // 开始设置表格
                List<TableColumn> columns = new ArrayList<TableColumn>();
                Map<String, String> stringStringMap = staticMap.get(integer);
                for (int i = 0; i < list.size(); i++) {
                    TableColumn column = new TableColumn();
                    //设置表名
                    column.setName(list.get(i));
                    //设置表备注
                    String bz = stringStringMap.get(list.get(i));
                    column.setComment(bz);

                    column.setType(list1.get(i));
                    if(list1.get(i).equalsIgnoreCase("varchar")){
                        column.setLength(100);
                    } else if (list1.get(i).equalsIgnoreCase("decimal")) {
                        column.setLength(20);
                    }
                    columns.add(column);
                }
                map.put(integer, columns);
                map1.put("table",map);

                // 设置数据集合
                XSSFSheet sheet = excel.getSheetAt(integer);
                //行数
                int lastRowNum = sheet.getLastRowNum();

                List<Map<String,Object>> tableInserts = new ArrayList<>();
                //从确定表字段名的下一行开始取数据
                for (int i = Integer.parseInt(string) + 1; i <= lastRowNum; i++) {
                    XSSFRow row = sheet.getRow(i);

                    Map<String,Object> objectMap = new HashMap<>();

                    for (int j = 0; j < list.size(); j++) { //一共的列数等于设置数据库表的列数
                        XSSFCell cell = row.getCell(j);
                        String stringCellValue;
                        if(cell != null){
                            switch (cell.getCellType()) {
                                case HSSFCell.CELL_TYPE_STRING:
                                    stringCellValue = cell.getStringCellValue();
                                    break;
                                case HSSFCell.CELL_TYPE_NUMERIC:
                                    if (DateUtil.isCellDateFormatted(cell)) {
                                        stringCellValue = DateUtils.parseDate2String(cell.getDateCellValue());
                                    } else {
                                        // 数字以原格式输出，避免添加0
                                        DataFormatter formatter = new DataFormatter();
                                        stringCellValue = formatter.formatCellValue(cell);
                                        // 原格式输出后若千位加逗号，去除逗号
                                        stringCellValue = stringCellValue.replace(",","");
                                    }
                                    break;
                                case HSSFCell.CELL_TYPE_BOOLEAN:
                                    stringCellValue = String.valueOf(cell.getBooleanCellValue());
                                    break;
                                case HSSFCell.CELL_TYPE_FORMULA:
                                    stringCellValue = cell.getCellFormula();
                                    break;
                                default:
                                    stringCellValue = "";
                            }
                        }else {
                            stringCellValue = "";
                        }
                        //每一列的数据对应
                        objectMap.put(list.get(j),stringCellValue);
                    }
                    // 每一行的数据
                    tableInserts.add(objectMap);
                }
                // 每张表的数据
                listList.add(tableInserts);
            }
            map2.put(integer,listList);
        }
        map1.put("tableIn",map2);

        // 清除数据
        staticMap.clear();
        return map1;
    }

    public static Map<String,Object> getTableColumnsXLS(HSSFWorkbook excel) throws Exception {
        //有几张表创建几个数据库
        int sheets = excel.getNumberOfSheets();

        // 获取设置字段名
        Map<Integer, Map<String, List<String>>> mapMap = setValuesXLS(excel, sheets);

        Map<String,Object> map1 = new HashMap<>();

        Map<Integer,List<TableColumn>> map = new HashMap<>();
        // 设置字段类型
        // 确定从第几行开始循环往下确定数据类型
        Set<Integer> integers = mapMap.keySet();

        Map<Integer,List<List<Map<String,Object>>>> map2 = new HashMap<>();

        for (Integer integer : integers) {
            List<List<Map<String,Object>>> listList = new ArrayList<>();

            Map<String, List<String>> stringListMap = mapMap.get(integer);
            Set<String> strings = stringListMap.keySet();
            for (String string : strings) { //此循环实际上肯定只有一个
                List<String> list = stringListMap.get(string);
                //依次取出列名，对出现重复名称的列名做处理
                for (int i = 0; i < list.size(); i++) {
                    for (int j = i + 1; j < list.size(); j++) {
                        if(list.get(i).equals(list.get(j))){//依次和后面数据比较，若出现相同名，则修改
                            String s = list.get(j);
                            String new_name = s + "_"+ j; //将该重名项后添加对应列数信息，防止重名
                            list.set(j, new_name);
                        }
                    }
                }

                List<String> list1 = setValuesTypeXLS(excel, integer, string, list.size());

                // 开始设置表格
                List<TableColumn> columns = new ArrayList<TableColumn>();

                Map<String, String> stringStringMap = staticMap.get(integer);
                for (int i = 0; i < list.size(); i++) {
                    TableColumn column = new TableColumn();
                    column.setName(list.get(i));

                    //设置表备注
                    String bz = stringStringMap.get(list.get(i));
                    column.setComment(bz);
                    column.setType(list1.get(i));
                    if(list1.get(i).equalsIgnoreCase("varchar")){
                        column.setLength(100);
                    } else if (list1.get(i).equalsIgnoreCase("decimal")) {
                        column.setLength(20);
                    }
                    columns.add(column);
                }
                map.put(integer, columns);
                map1.put("table",map);

                // 设置数据集合
                HSSFSheet sheet = excel.getSheetAt(integer);
                //行数
                int lastRowNum = sheet.getLastRowNum();

                List<Map<String,Object>> tableInserts = new ArrayList<>();
                //从确定表字段名的下一行开始取数据
                for (int i = Integer.parseInt(string) + 1; i <= lastRowNum; i++) {
                    HSSFRow row = sheet.getRow(i);

                    Map<String,Object> objectMap = new HashMap<>();

                    for (int j = 0; j < list.size(); j++) { //一共的列数等于设置数据库表的列数
                        HSSFCell cell = row.getCell(j);
                        String stringCellValue;
                        if(cell != null){
                            switch (cell.getCellType()) {
                                case HSSFCell.CELL_TYPE_STRING:
                                    stringCellValue = cell.getStringCellValue();
                                    break;
                                case HSSFCell.CELL_TYPE_NUMERIC:
                                    if (DateUtil.isCellDateFormatted(cell)) {
                                        stringCellValue = DateUtils.parseDate2String(cell.getDateCellValue());
                                    } else {
                                        // 数字以原格式输出，避免添加0
                                        DataFormatter formatter = new DataFormatter();
                                        stringCellValue = formatter.formatCellValue(cell);
                                        // 原格式输出后若千位加逗号，去除逗号
                                        stringCellValue = stringCellValue.replace(",","");
                                    }
                                    break;
                                case HSSFCell.CELL_TYPE_BOOLEAN:
                                    stringCellValue = String.valueOf(cell.getBooleanCellValue());
                                    break;
                                case HSSFCell.CELL_TYPE_FORMULA:
                                    stringCellValue = cell.getCellFormula();
                                    break;
                                default:
                                    stringCellValue = "";
                            }
                        }else {
                            stringCellValue = "";
                        }
                        //每一列的数据对应
                        objectMap.put(list.get(j),stringCellValue);
                    }
                    // 每一行的数据
                    tableInserts.add(objectMap);
                }
                // 每张表的数据
                listList.add(tableInserts);
            }
            map2.put(integer,listList);
        }
        map1.put("tableIn",map2);

        // 清除数据
        staticMap.clear();
        return map1;
    }

    // 设置每列的数据类型
    private static List<String> setValuesTypeXLSX(XSSFWorkbook excel, Integer integer, String string, Integer lc) {
        //表字段类型集合
        List<String> values = new ArrayList<>();
        // 实际此key只有一个，确定的某一行
        XSSFSheet sheet = excel.getSheetAt(integer);
        //行数
        int lastRowNum = sheet.getLastRowNum();

        String stringCellValue = "";
        // 列循环次数
        for (int i = 0; i < lc; i++){
            // 记录该类型被赋予次数
//            int num = 0;
            // 以该行的下一行开始获取数据类型
            for (int j = Integer.parseInt(string) + 1; j < lastRowNum; j++) {
                XSSFRow row = sheet.getRow(j);
                XSSFCell cell = row.getCell(i);
                if (cell != null) {
                    switch (cell.getCellType()) {
                        case HSSFCell.CELL_TYPE_STRING:
                            // 字符串类型
                            stringCellValue = "VARCHAR";
//                            num ++;
                            break;
                        case HSSFCell.CELL_TYPE_NUMERIC:
                            if (DateUtil.isCellDateFormatted(cell)) {
                                // 日期类型
                                stringCellValue = "datetime";
                            } else {
                                // 数字类型
                                stringCellValue = "decimal";
                            }
//                            num ++;
                            break;
                        case HSSFCell.CELL_TYPE_BOOLEAN:
                            // 也存储为字符串
                            stringCellValue = "VARCHAR";
//                            num ++;
                            break;
                        case HSSFCell.CELL_TYPE_FORMULA:
                            stringCellValue = "VARCHAR";
//                            num ++;
                            break;
                        default:
                            // 都不是的类型，或者此处数据为空，继续找该列下一行数据，直到找完所有行
                            continue;
                    }

//                    if(num >=2){ //两次被设置为同一类型，
//
//                    }
                }
                if(!StringUtils.isEmpty(stringCellValue)){ //已经找到有数据的行，则直接以此数据类型设置
                    values.add(stringCellValue);
                    // 结束此列数据类型设置
                    break;
                }

            }

            if(StringUtils.isEmpty(stringCellValue)){ //该列数据每一行都是空，没有数据，则默认设置为字符串
                values.add("VARCHAR");
            }

        }
        return values;
    }

    // 设置每列的数据类型
    private static List<String> setValuesTypeXLS(HSSFWorkbook excel, Integer integer, String string, Integer lc) {
        //表字段类型集合
        List<String> values = new ArrayList<>();
        // 实际此key只有一个，确定的某一行
        HSSFSheet sheet = excel.getSheetAt(integer);
        //行数
        int lastRowNum = sheet.getLastRowNum();

        // 列循环次数
        for (int i = 0; i < lc; i++){
            String stringCellValue = "";
            // 记录该类型被赋予次数
//            int num = 0;
            // 以该行的下一行开始获取数据类型
            for (int j = Integer.parseInt(string) + 1; j <= lastRowNum; j++) {
                HSSFRow row = sheet.getRow(j);
                HSSFCell cell = row.getCell(i);
                if (cell != null) {
                    switch (cell.getCellType()) {
                        case HSSFCell.CELL_TYPE_STRING:
                            // 字符串类型
                            stringCellValue = "VARCHAR";
//                            num ++;
                            break;
                        case HSSFCell.CELL_TYPE_NUMERIC:
                            if (DateUtil.isCellDateFormatted(cell)) {
                                // 日期类型
                                stringCellValue = "datetime";
                            } else {
                                // 数字类型
                                stringCellValue = "decimal";
                            }
//                            num ++;
                            break;
                        case HSSFCell.CELL_TYPE_BOOLEAN:
                            // 也存储为字符串
                            stringCellValue = "VARCHAR";
//                            num ++;
                            break;
                        case HSSFCell.CELL_TYPE_FORMULA:
                            stringCellValue = "VARCHAR";
//                            num ++;
                            break;
                        default:
                            // 都不是的类型，或者此处数据为空，继续找该列下一行数据，直到找完所有行
                            continue;
                    }

//                    if(num >=2){ //两次被设置为同一类型，
//
//                    }
                }

                if(StringUtils.isNotEmpty(stringCellValue)){ //已经找到有数据的行，则直接以此数据类型设置
                    values.add(stringCellValue);
                    // 结束此列数据类型设置
                    break;
                }

            }

            if(StringUtils.isEmpty(stringCellValue)){ //该列数据每一行都是空，没有数据，则默认设置为字符串
                values.add("VARCHAR");
            }

        }
        return values;
    }

    /**
     * 设置字段名
     * 返回为：第一层，第几张表，第二层，第几行的数据确定的表字段名
     * */
    public static Map<Integer,Map<String, List<String>>> setValuesXLSX(XSSFWorkbook excel, int sheets) {
        Map<Integer,Map<String, List<String>>> mapMap = new HashMap<>();

        for (int i = 0; i < sheets; i++) {
            XSSFSheet sheet = excel.getSheetAt(i);
            // 字段名集合
            List<String> res_list = new ArrayList<>();
            // 最终取的行
            Integer res_h = 0;
            Map<String,List<String>> map = new HashMap<>();

            //行数
            int lastRowNum = sheet.getLastRowNum() + 1;

            List<String> temp = List.of();
            //以第一次出现的最长不为空的行为基础创建表
            for (int j = 0; j < lastRowNum; j++) {
                List<String> list = new ArrayList<>();

                XSSFRow row1 = sheet.getRow(j);
                if(row1 != null){
                    // 该行列数
                    int lastCellNum = row1.getLastCellNum();
                    for (int k = 0; k < lastCellNum; k++) {
                        XSSFCell cell = row1.getCell(k);
                        // 保持原始内容
                        DataFormatter formatter = new DataFormatter();
                        String stringCellValue = formatter.formatCellValue(cell);
                        if(!StringUtils.isEmpty(stringCellValue)){
                            list.add(stringCellValue);
                        }
                    }
                }

                // 比较该行和上一行的长度大小
                if(j != 0){ //从第二行开始
                    if(temp.size() < list.size()){
                        temp = list;
                        // 发生变化时，变成对应的行
                        res_h = j;
                    }
                }else {
                    // 存储为已知最长的一行的信息
                    temp = list;
                    res_h = j; //初始为第一行
                }

            }
            //取出每一行，并重新赋值为首拼音
            for (String s : temp) {
                String firstLetters = PinyinUtils.getFirstLetters(s);
                // 对命名做规范处理
                String name = PinyinUtils.sanitizeTableName(firstLetters);
                res_list.add(name);
            }

            Map<String,String> map1 = new HashMap<>();
            List<String> res_name = new ArrayList<>();
            // 由于代码太多，改起来太麻烦，现在将添加注释的所有注释另外返回--此处再修改返回类型改起来麻烦，直接采用本地redis存取
            for (int j = 0; j < temp.size(); j++) {
                String s = temp.get(j);
                String firstLetters = PinyinUtils.getFirstLetters(s);
                // 对命名做规范处理
                String name = PinyinUtils.sanitizeTableName(firstLetters);
                res_name.add(name);
            }
            /**
             * 处理完后对重名做处理
             * 例如：ql:清理；ql:权利，这样key相同数据会覆盖
             * */
            for (int j = 0; j < res_name.size(); j++) {
                for (int k = j+1; k < res_name.size(); k++) {
                    // 依次与后面的数据比较，若相同则添加对应序列
                    if(res_name.get(j).equals(res_name.get(k))){
                        String s = res_name.get(j);
                        res_name.remove(k);
                        res_name.add(k,s+"_"+k);
                    }
                }
            }

            for (int j = 0; j < temp.size(); j++) {
                map1.put(res_name.get(j),temp.get(j));
            }



            Map<Integer,Map<String,String>> mapH = new HashMap<>();
            mapH.put(res_h,map1);
            stMap.put(i,mapH);
            staticMap.put(i,map1);

            map.put(String.valueOf(res_h),res_list);
            mapMap.put(i,map);
        }

        return mapMap;
    }

    /**
     * 设置字段名
     * 返回为：第一层，第几张表，第二层，第几行的数据确定的表字段名
     * */
    private static Map<Integer,Map<String, List<String>>> setValuesXLS(HSSFWorkbook excel, int sheets) {
        Map<Integer,Map<String, List<String>>> mapMap = new HashMap<>();

        for (int i = 0; i < sheets; i++) {
            HSSFSheet sheet = excel.getSheetAt(i);
            // 字段名集合
            List<String> res_list = new ArrayList<>();
            // 最终取的行
            Integer res_h = 0;
            Map<String,List<String>> map = new HashMap<>();

            //行数
            int lastRowNum = sheet.getLastRowNum();

            List<String> temp = List.of();
            //以第一次出现的最长不为空的行为基础创建表
            for (int j = 0; j < lastRowNum; j++) {
                List<String> list = new ArrayList<>();

                HSSFRow row1 = sheet.getRow(j);
                if(row1 != null){
                    // 该行列数
                    int lastCellNum = row1.getLastCellNum();
                    for (int k = 0; k < lastCellNum; k++) {
                        HSSFCell cell = row1.getCell(k);
                        // 保持原始内容
                        DataFormatter formatter = new DataFormatter();
                        String stringCellValue = formatter.formatCellValue(cell);
                        if(!StringUtils.isEmpty(stringCellValue)){
                            list.add(stringCellValue);
                        }
                    }
                }

                // 比较该行和上一行的长度大小
                if(j != 0){ //从第二行开始
                    if(temp.size() < list.size()){
                        temp = list;
                        // 发生变化时，变成对应的行
                        res_h = j;
                    }
                }else {
                    // 存储为已知最长的一行的信息
                    temp = list;
                    res_h = j; //初始为第一行
                }

            }
            //取出每一行，并重新赋值为首拼音
            for (String s : temp) {
                String firstLetters = PinyinUtils.getFirstLetters(s);
                // 对命名做规范处理
                String name = PinyinUtils.sanitizeTableName(firstLetters);
                res_list.add(name);
            }

            Map<String,String> map1 = new HashMap<>();
            List<String> res_name = new ArrayList<>();
            // 由于代码太多，改起来太麻烦，现在将添加注释的所有注释另外返回--此处再修改返回类型改起来麻烦，直接采用本地redis存取
            for (int j = 0; j < temp.size(); j++) {
                String s = temp.get(j);
                String firstLetters = PinyinUtils.getFirstLetters(s);
                // 对命名做规范处理
                String name = PinyinUtils.sanitizeTableName(firstLetters);
                res_name.add(name);
            }
            /**
             * 处理完后对重名做处理
             * 例如：ql:清理；ql:权利，这样key相同数据会覆盖
             * */
            for (int j = 0; j < res_name.size(); j++) {
                for (int k = j+1; k < res_name.size(); k++) {
                    // 依次与后面的数据比较，若相同则添加对应序列
                    if(res_name.get(j).equals(res_name.get(k))){
                        String s = res_name.get(j);
                        res_name.remove(k);
                        res_name.add(k,s+"_"+k);
                    }
                }
            }

            for (int j = 0; j < temp.size(); j++) {
                map1.put(res_name.get(j),temp.get(j));
            }



            Map<Integer,Map<String,String>> mapH = new HashMap<>();
            mapH.put(res_h,map1);
            stMap.put(i,mapH);
            staticMap.put(i,map1);

            map.put(String.valueOf(res_h),res_list);
            mapMap.put(i,map);
        }

        return mapMap;
    }
}
